Skip to content

Conversation

jdcormie
Copy link
Member

@jdcormie jdcormie commented Aug 20, 2025

Part 1 of fixing #12293. No behavior change intended this is a pure refactor.

jdcormie and others added 30 commits August 19, 2025 17:21
# Conflicts:
#	binder/src/main/java/io/grpc/binder/internal/BinderTransport.java
# Conflicts:
#	binder/src/main/java/io/grpc/binder/internal/BinderTransport.java
# Conflicts:
#	binder/src/main/java/io/grpc/binder/internal/BinderTransport.java
# Conflicts:
#	binder/src/main/java/io/grpc/binder/internal/BinderTransport.java
# Conflicts:
#	binder/src/main/java/io/grpc/binder/internal/BinderTransport.java
# Conflicts:
#	binder/src/main/java/io/grpc/binder/internal/BinderTransport.java
# Conflicts:
#	binder/src/main/java/io/grpc/binder/internal/BinderTransport.java
# Conflicts:
#	binder/src/main/java/io/grpc/binder/internal/BinderTransport.java
@jdcormie jdcormie marked this pull request as ready for review September 16, 2025 21:25
@jdcormie
Copy link
Member Author

@mateusazis PTAL

if (readyTimeoutFuture != null) {
readyTimeoutFuture.cancel(false);
readyTimeoutFuture = null;
class LegacyClientHandshake extends ClientHandshake {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: final and private

int remoteUid = Binder.getCallingUid();
restrictIncomingBinderToCallsFrom(remoteUid);
attributes = setSecurityAttrs(attributes, remoteUid);
authResultFuture = checkServerAuthorizationAsync(remoteUid);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the plans for the next PR, but it seems like authResultFuture is never used by the parent class anymore except during cancellation.

It feels a bit weird to see one class setting another one's fields, even if they are nested. Could we move authResultFuture into this one and add a cancel method to ClientHandshake?

Ditto possibly for attributes; couldn't fully track all the places where it is used.

*
* <p>Supports a clean migration away from the legacy approach, one client at a time.
*/
abstract class ClientHandshake {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we design at as an interface instead?

go/ej3e-20

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No because I want its methods to be @GuardedBy("BinderClientTransport.this") which isn't well defined for an interface or anything but an inner class.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we apply the annotation to the BinderClientTransport.handshake field instead and then use an interface?

Either with an interface or an abstract class, it sounds weird to guard a method based on another class's fields (despite the outer-inner class relationship). Feels like we have a purely abstract API making very strong assumptions about its call site.

*
* <p>Supports a clean migration away from the legacy approach, one client at a time.
*/
abstract class ClientHandshake {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: private

int remoteUid = Binder.getCallingUid();
restrictIncomingBinderToCallsFrom(remoteUid);
attributes = setSecurityAttrs(attributes, remoteUid);
authResultFuture = checkServerAuthorizationAsync(remoteUid);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if authResultFuture could be a local variable, so it gets garbage-collected once the auth is over and we don't need it anymore. I see we need to keep it around to support cancellation though.

Could we clear it after it completes?

Another pattern I have seen is to keep a collection of "cancellable stuff (or futures)" and just remove items when they are no longer subject to cancellation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, authResultFuture holds the result of evaluating a long-blocking or async SecurityPolicy so we want to cancel it if this transport instance terminates before it completes. All implementations of ClientHandshake will evaluate the SecurityPolicy (just at different times) and all will want this same cancellation behavior so I'd like to leave the future and cancellation code as it is.

We could certainly clear this future after completion or put it in a collection but the current code doesn't do this and my goal with this PR is no behavior changes in a way that's obvious by inspection. LMK if you feel strongly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. Agreed that this is an optimization that we do not need to do right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants